package org.hbgl.geoentity.db.service;

import com.github.pagehelper.PageHelper;
import org.apache.commons.lang3.StringUtils;
import org.hbgl.geoentity.db.dao.GeAuthMapper;
import org.hbgl.geoentity.db.dao.GeNodeMapper;
import org.hbgl.geoentity.db.dao.GeUnitMapper;
import org.hbgl.geoentity.db.domain.*;
import org.hbgl.geoentity.db.util.*;
import org.hbgl.geoentity.db.vo.AnalyRecordVo;
import org.hbgl.geoentity.db.vo.NodeApplyVo;
import org.hbgl.geoentity.db.vo.NodeVo;
import org.hbgl.geoentity.db.vo.UnitVo;
import org.springframework.beans.BeanUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 代码功能：
 * 开发日期：2022/4/22
 * 作者：蒋海仑
 * 联系方式：
 * 版本更迭说明：
 * 版权信息：河北广联信息技术有限公司
 */
@Service
public class NodeService {
    @Resource
    private GeNodeMapper nodeMapper;
    @Resource
    private GeUnitMapper unitMapper;
    @Resource
    private GeAuthMapper authMapper;

    public List<GeNode> findByNodeIdcode(String nodeIdcode) {
        GeNodeExample example = new GeNodeExample();
        example.or().andNodeIdcodeEqualTo(nodeIdcode).andStateNotEqualTo(EnumFile.CommonState.Delete);
        return nodeMapper.selectByExample(example);
    }

    public List<GeNode> findByNodeIdcode(Integer nodeId, String nodeIdcode) {
        GeNodeExample example = new GeNodeExample();
        example.or().andIdNotEqualTo(nodeId).andNodeIdcodeEqualTo(nodeIdcode).andStateNotEqualTo(EnumFile.CommonState.Delete);
        return nodeMapper.selectByExample(example);
    }

    public List<GeUnit> findUnit(String unitName) {
        GeUnitExample example = new GeUnitExample();
        example.or().andUnitNameEqualTo(unitName);
        return unitMapper.selectByExample(example);
    }

    public List<NodeVo> selectNodeList(String area, String keywords, Integer page, Integer limit) {
        PageHelper.startPage(page, limit);
        return nodeMapper.selectNodeList(area, keywords);
    }


    public List<NodeVo> selectNodeForShow() {
        return nodeMapper.selectNodeList(null, null);
    }

    public List<NodeVo> selectNodeListNew(Integer nodeType, Integer examState, String keywords, Integer page, Integer limit) {
        PageHelper.startPage(page, limit);
        return nodeMapper.selectNodeListNew(nodeType, examState, keywords);
    }


    @Transactional
    public void add(NodeVo nodeVo) {
        //通过节点申请id获取节点申请详情
        NodeApplyVo nodeApplyById = nodeMapper.findNodeApplyById(nodeVo.getNodeId());
        GeNodeApply geNodeApply = new GeNodeApply();
        geNodeApply.setId(nodeVo.getNodeId());
        geNodeApply.setIfAdd(EnumFile.IfAddState.Added);
        nodeMapper.updateNodeApplyById(geNodeApply);
        GeNode node = new GeNode();
        node.setParentId(1);
        node.setNodeLevel(2);
        node.setUnitId(nodeVo.getUnitId());
        node.setNodeIdcode(nodeVo.getNodeIdcode());
        node.setNodeName(nodeApplyById.getNodeName());
        node.setState(EnumFile.CommonState.Normal);
        node.setAddTime(LocalDateTime.now());
        node.setEditTime(LocalDateTime.now());
        node.setNodeType(nodeVo.getNodeType());
        node.setContractAgreement(nodeVo.getContractAgreement());
        node.setExamState(EnumFile.ExamineState.Wait);
        nodeMapper.insert(node);
        // 生成应用密匙
        String appKey = RamdonCode();
        appKey += BaseID(node.getId());
        appKey = appKey.toUpperCase();
        GeNode geNode = new GeNode();
        geNode.setId(node.getId());
        geNode.setAppKey(appKey);
        geNode.setAppSecret(MD5Encrypt.GetMD5String(appKey, appKey));
        nodeMapper.updateByPrimaryKeySelective(geNode);
        GeUnit unit = new GeUnit();
        // BeanUtils.copyProperties(nodeVo, unit);
        // unit.setState(EnumFile.CommonState.Normal);
        // unit.setAddTime(LocalDateTime.now());
        unit.setId(nodeVo.getUnitId());
        GeUnit geUnit = unitMapper.selectByPrimaryKey(nodeVo.getUnitId());
        if (!geUnit.getLinkman().equals(nodeVo.getLinkman()) || !geUnit.getLinkphone().equals(nodeVo.getLinkphone())) {
            unit.setEditTime(LocalDateTime.now());
            unit.setLinkman(nodeVo.getLinkman());
            unit.setLinkphone(nodeVo.getLinkphone());
            unitMapper.updateByPrimaryKeySelective(unit);
        }

        // unitMapper.insert(unit);

        /**GeAuth auth = new GeAuth();
         auth.setId(nodeVo.getId());
         // auth.setNodeId(node.getId());
         // auth.setUnitId(unit.getId());
         // auth.setAuthDate(LocalDateTime.now());
         // auth.setState(EnumFile.CommonState.Normal);
         // auth.setAddTime(LocalDateTime.now());
         // auth.setEditTime(LocalDateTime.now());
         // authMapper.insert(auth);
         auth.setNodeId(nodeVo.getId());
         // 生成应用密匙
         // String appKey = RamdonCode();
         // appKey += BaseID(node.getId());
         // appKey = appKey.toUpperCase();
         // auth.setAppKey(appKey);
         // auth.setAppSecret(MD5Encrypt.GetMD5String(appKey, appKey));
         authMapper.updateByPrimaryKeySelective(auth);

         // BeanUtils.copyProperties(auth, nodeVo);*/
    }

    //region 获取随机数

    /**
     * 获取随机数据
     *
     * @return 数组中的数据
     */
    public String RamdonCode() {
        try {
            List<String> list = new ArrayList<>();
            ClassPathResource classPathResource = new ClassPathResource("/SourceFile/1000.txt");
            InputStream inputStream = classPathResource.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String lineTxt;
            while ((lineTxt = bufferedReader.readLine()) != null && !lineTxt.isEmpty()) {
                list.add(lineTxt);
            }
            bufferedReader.close();
            int index = (int) (Math.random() * list.size());
            return list.get(index);
        } catch (Exception e) {
            return "";
        }
    }
    //endregion
    //region 转化成16进制

    /**
     * 转化成16进制
     *
     * @param MaxID 最大ID
     * @return ID
     */
    public String BaseID(Integer MaxID) {
        StringBuilder ConCode = new StringBuilder();
        String id = Integer.toHexString(MaxID);
        if (id.length() != 7) {
            int length = id.length();
            switch (length) {
                case 1:
                    id = "000000" + id;
                    break;
                case 2:
                    id = "00000" + id;
                    break;
                case 3:
                    id = "0000" + id;
                    break;
                case 4:
                    id = "000" + id;
                    break;
                case 5:
                    id = "00" + id;
                    break;
                case 6:
                    id = "0" + id;
                    break;
            }
            char[] newid = id.toCharArray();
            for (char ch : newid) {
                switch (ch) {
                    case '0':
                        ConCode.append("a");
                        break;
                    case '1':
                        ConCode.append("b");
                        break;
                    case '2':
                        ConCode.append("c");
                        break;
                    case '3':
                        ConCode.append("d");
                        break;
                    case '4':
                        ConCode.append("e");
                        break;
                    case '5':
                        ConCode.append("f");
                        break;
                    case '6':
                        ConCode.append("g");
                        break;
                    case '7':
                        ConCode.append("h");
                        break;
                    case '8':
                        ConCode.append("i");
                        break;
                    case '9':
                        ConCode.append("j");
                        break;
                    case 'a':
                        ConCode.append("k");
                        break;
                    case 'b':
                        ConCode.append("l");
                        break;
                    case 'c':
                        ConCode.append("m");
                        break;
                    case 'd':
                        ConCode.append("n");
                        break;
                    case 'e':
                        ConCode.append("o");
                        break;
                    case 'f':
                        ConCode.append("p");
                        break;
                }
            }
        }
        return ConCode.toString();
    }
    //endregion

    public NodeVo findById(Integer id) {
        return nodeMapper.selectNodeById(id);
    }

    public int updateById(NodeVo nodeVo) {
        GeNode node = new GeNode();
        BeanUtils.copyProperties(nodeVo, node);
        node.setId(nodeVo.getNodeId());
        node.setEditTime(LocalDateTime.now());
        // nodeMapper.updateByPrimaryKeySelective(node);
        // GeUnit unit = new GeUnit();
        // BeanUtils.copyProperties(nodeVo, unit);
        // unit.setEditTime(LocalDateTime.now());
        // unitMapper.updateByPrimaryKeySelective(unit);
        //
        // GeAuth auth = new GeAuth();
        // auth.setId(nodeVo.getId());
        // auth.setNodeId(nodeVo.getNodeId());
        // auth.setEditTime(LocalDateTime.now());
        // return authMapper.updateByPrimaryKeySelective(auth);
        return nodeMapper.updateByPrimaryKeySelective(node);
    }

    public int updateStateById(Integer id, Integer state) {
        GeNode node = new GeNode();
        node.setId(id);
        node.setState(state);
        node.setEditTime(LocalDateTime.now());
        return nodeMapper.updateByPrimaryKeySelective(node);
    }

    public int updateByIdSelective(NodeVo nodeVo) {
        GeNode node = new GeNode();
        BeanUtils.copyProperties(nodeVo, node);
        node.setEditTime(LocalDateTime.now());
        return nodeMapper.updateByPrimaryKeySelective(node);
    }

    public int deleteByIdLogical(Integer id) {
        GeAuth auth = authMapper.selectByPrimaryKey(id);

        GeUnit unit = new GeUnit();
        unit.setId(auth.getUnitId());
        unit.setState(EnumFile.CommonState.Delete);
        unit.setEditTime(LocalDateTime.now());
        unitMapper.updateByPrimaryKeySelective(unit);

        GeNode node = new GeNode();
        node.setId(auth.getNodeId());
        node.setState(EnumFile.CommonState.Delete);
        node.setEditTime(LocalDateTime.now());
        nodeMapper.updateByPrimaryKeySelective(node);

        auth.setState(EnumFile.CommonState.Delete);
        auth.setEditTime(LocalDateTime.now());
        return authMapper.updateByPrimaryKeySelective(auth);
    }

    public GeNode findByParentId(Integer parentId) {
        GeNodeExample example = new GeNodeExample();
        example.or().andParentIdEqualTo(parentId);
        return nodeMapper.selectOneByExample(example);
    }

    public Long selectNodeCount() {
        GeNodeExample example = new GeNodeExample();
        example.or().andStateEqualTo(EnumFile.CommonState.Normal).andExamStateEqualTo(EnumFile.ExamineState.Passed);
        return nodeMapper.countByExample(example);
    }

    public List<GeUnit> selectUnitListAll() {
        return nodeMapper.selectUnitListAll();
    }

    public List<GeNodeApply> findNodeApplyByUnitId(Integer unitId) {
        return nodeMapper.findNodeApplyByUnitId(unitId, EnumFile.ExamineState.Wait);
    }

    public List<GeNodeApply> findNodeBoxByUnitId(Integer unitId) {
        return nodeMapper.findNodeApplyByUnitId(unitId, EnumFile.ExamineState.Passed);
    }

    public List<NodeApplyVo> selectNodeApplyList(String area, String keywords, Integer page, Integer limit) {
        PageHelper.startPage(page, limit);
        return nodeMapper.selectNodeApplyList(area, keywords);
    }

    public List<NodeApplyVo> selectNodeApplyList(Integer unitId, String area, Integer state, String keywords, Integer page, Integer limit) {
        PageHelper.startPage(page, limit);
        return nodeMapper.queryNodeApplyList(unitId, area, state, keywords);
    }

    public List<NodeApplyVo> selectNodeApplyExamList(String area, String keywords, List<Integer> examState, Integer page, Integer limit) {
        PageHelper.startPage(page, limit);
        return nodeMapper.selectNodeApplyExamList(area, keywords, examState);
    }

    public NodeApplyVo findNodeApplyById(Integer id) {
        return nodeMapper.findNodeApplyById(id);
    }

    public int delNodeApplyById(Integer id) {
        return nodeMapper.delNodeApplyById(id);
    }

    public int delNodeByApplyId(Integer id) {
        return nodeMapper.delNodeByApplyId(id);
    }

    @Transactional
    public int nodeApplyExamine(GeNodeApply nodeApply, boolean GYHLW_COMPANYINFO_REPORTING, Integer examNum) {
        nodeApply.setEditTime(LocalDateTime.now());
        if (nodeApply.getState().equals(EnumFile.ExamineState.Passed)) {
            nodeApply.setIfAdd(EnumFile.IfAddState.Added);
        }
        int i = nodeMapper.updateNodeApplyById(nodeApply);
        if (examNum == EnumFile.ExamineState.Passed) {
            // if(nodeApply.getState().equals(EnumFile.ExamineState.Passed)) {
            //通过节点申请id获取节点申请详情
            NodeApplyVo gnodeApply = nodeMapper.findNodeApplyById(nodeApply.getId());
            GeNode node = new GeNode();
            node.setApplyId(nodeApply.getId());
            node.setParentId(1);
            node.setNodeLevel(2);
            node.setUnitId(gnodeApply.getUnitId());
            node.setNodeIdcode(gnodeApply.getNodeIdcode());
            node.setNodeName(gnodeApply.getNodeName());
            node.setState(EnumFile.CommonState.Normal);
            node.setAddTime(LocalDateTime.now());
            node.setEditTime(LocalDateTime.now());
            node.setRemark(gnodeApply.getRemark());
            node.setNodeProfile(gnodeApply.getNodeProfile());
            // node.setNodeType(nodeVo.getNodeType());
            node.setProvinceCode(gnodeApply.getProvinceCode());
            node.setCityCode(gnodeApply.getCityCode());
            node.setAreaCode(gnodeApply.getAreaCode());
            node.setContractAgreement(gnodeApply.getContractAgreement());
            node.setExamState(nodeApply.getState());
            node.setExamTime(LocalDateTime.now());
            i = nodeMapper.insert(node);
            // 生成应用密匙
            String appKey = RamdonCode();
            appKey += BaseID(node.getId());
            appKey = appKey.toUpperCase();
            GeNode geNode = new GeNode();
            geNode.setId(node.getId());
            geNode.setAppKey(appKey);
            geNode.setAppSecret(MD5Encrypt.GetMD5String(appKey, appKey));
            i = nodeMapper.updateByPrimaryKeySelective(geNode);
            // unitMapper.insert(unit);
            // }
            if (i > 0) {
                if (GYHLW_COMPANYINFO_REPORTING) {
                    //节点审核通过将数据上传到工业互联网平台
//                    if(nodeApply.getState().equals(EnumFile.ExamineState.Passed)) {
//                        UnitVo unit = unitMapper.selectUnitById(gnodeApply.getUnitId());
//                        if(unit!=null) {
//                            //同步到工业互联网平台
//                            String url= ApiUrlConfig.GYHLW_COMPANYINFO_REPORTING;
//                            Map<String,Object> params=new HashMap<String,Object>();
//                            params.put("access_token", ApiUrlConfig.ACCESS_TOKEN);
//                            params.put("organunitname",unit.getUnitName());
//                            params.put("nodecode",gnodeApply.getNodeIdcode());
//                            params.put("unittype_id",unit.getUnitType());
//                            params.put("organunitaddress",unit.getUnitAddress());
//                            params.put("province_id",unit.getProvinceCode());
//                            params.put("city_id",unit.getCityCode());
//                            params.put("area_id",unit.getAreaCode());
//                            params.put("codepaytype", 2);
//                            params.put("organizationcode", unit.getUnitCode());
//                            params.put("corporate", unit.getCorporation());
//                            params.put("corporate_credentials_type", 1);
//                            params.put("corporate_credentials", unit.getCredentials());
//                            params.put("trade_id", unit.getTradeId());
//                            params.put("linkman", unit.getLinkman());
//                            params.put("linkphone", unit.getLinkphone());
//                            params.put("email", unit.getEmail());
//                            params.put("time", System.currentTimeMillis());
//                            Result result = new IdcodeApiExecute<Result>().
//                                    execute(Result.class,params,url,true);
//                            try {
//                                if(result.getResultCode()==1) {
                    nodeApply.setIsEscalation(1);
                    nodeApply.setEscalationTime(LocalDateTime.now());
                    nodeMapper.updateNodeApplyById(nodeApply);
                    return 1;
//                                }else if(result.getResultCode()==2) { //已存在该组织单位，不可再添加！
//                                    return 1;
//                                }else {
//                                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//                                    return 0;
//                                }
//                            }catch (Exception e) {
//                                e.printStackTrace();
//                                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//                                return 0;
//                            }
//                        }
//                    }
                }
            }
        }

        return i;
    }

    public List<NodeVo> selectNodeExamlist(Integer nodeType, Integer examState, String keywords, Integer page, Integer limit) {
        PageHelper.startPage(page, limit);
        return nodeMapper.selectNodeExamlist(nodeType, examState, keywords);
    }

    public List<NodeVo> selectAuthExamlist(String area, String keywords, Integer page, Integer limit) {
        PageHelper.startPage(page, limit);
        return nodeMapper.selectAuthExamlist(area, keywords);
    }

    public List<NodeVo> selectAuthExamStatelist(String area, String keywords, List<Integer> examState, Integer page, Integer limit) {
        PageHelper.startPage(page, limit);
        return nodeMapper.selectAuthExamStatelist(area, keywords, examState);
    }

    public NodeVo findAuthById(Integer id) {
        return nodeMapper.findAuthById(id);
    }

    public List<NodeVo> findAuthByNodeId(Integer nodeId) {
        return nodeMapper.findAuthByNodeId(nodeId);
    }

    public List<GeNode> findNodeByApplyId(Integer applyId) {
        return nodeMapper.findNodeByApplyId(applyId);
    }

    public int deleteByPrimaryKey(Integer id) {
        return nodeMapper.deleteByPrimaryKey(id);
    }

    public int updateAuthById(Integer id, Integer authExamineState, String remark) {
        GeAuth auth = new GeAuth();
        auth.setId(id);
        auth.setAuthExamineState(authExamineState);
        auth.setRemark(remark);
        auth.setEditTime(LocalDateTime.now());
        auth.setAuthExamTime(LocalDateTime.now());
        int i = authMapper.updateByPrimaryKeySelective(auth);
        if (i > 0 && authExamineState.equals(EnumFile.ExamineState.Passed)) {
            GeNode node = new GeNode();
            node.setAuthState(EnumFile.IfAuthState.Authorized);
            NodeVo assessByAuthId = authMapper.findAssessByAuthId(id);
            node.setId(assessByAuthId.getNodeId());
            return nodeMapper.updateByPrimaryKeySelective(node);
        }
        return i;
    }

    public NodeVo findNodeById(Integer id) {
        return nodeMapper.findNodeById(id);
    }

    public int updateNodeById(Integer id, Integer examState, String remark) {
        GeNode node = new GeNode();
        node.setId(id);
        node.setExamState(examState);
        node.setRemark(remark);
        node.setState(EnumFile.CommonState.Normal);
        node.setEditTime(LocalDateTime.now());
        node.setExamTime(LocalDateTime.now());
        return nodeMapper.updateByPrimaryKeySelective(node);
    }

    public List<NodeVo> selectAuthDataList(Integer nodeType, String area, String keywords, String startTime, String endTime, Integer page, Integer limit) {
        PageHelper.startPage(page, limit);
        return nodeMapper.selectAuthDataList(nodeType, area, keywords, startTime, endTime);
    }

    public List<AnalyRecordVo> selectAnalyRecordList(Integer nodeType, String area, String keywords, String startTime, String endTime, Integer page, Integer limit) {
        PageHelper.startPage(page, limit);
        return nodeMapper.selectAnalyRecordList(nodeType, area, keywords, startTime, endTime);
    }

    public int createNodeApply(GeNodeApply nodeApply) {
        nodeApply.setState(0);
        nodeApply.setIfAdd(0);
//        String nodeIdcode = "MA.10001.";
//        if(StringUtils.isNotBlank(nodeApply.getAreaCode())) {
//            nodeApply.setNodeIdcode(nodeIdcode + nodeApply.getAreaCode());
//        }else if(StringUtils.isNotBlank(nodeApply.getCityCode())) {
//            nodeApply.setNodeIdcode(nodeIdcode + nodeApply.getCityCode());
//        }else{
//            nodeApply.setNodeIdcode(nodeIdcode + nodeApply.getProvinceCode());
//        }
        nodeApply.setAddTime(LocalDateTime.now());
        nodeApply.setEditTime(LocalDateTime.now());

        return nodeMapper.insertNodeApply(nodeApply);
    }

    public int updateNodeApply(GeNodeApply nodeApply) {
        nodeApply.setState(EnumFile.ExamineState.Wait);
        nodeApply.setIfAdd(EnumFile.IfAddState.Adding);
        nodeApply.setEditTime(LocalDateTime.now());
        GeNode geNode = new GeNode();
        geNode.setApplyId(nodeApply.getId());
        geNode.setExamState(EnumFile.ExamineState.Wait);
        nodeMapper.updateNodeExamStateByApplyId(nodeApply.getState(), nodeApply.getId());
//        String nodeIdcode = "MA.10001.";
//        if(StringUtils.isNotBlank(nodeApply.getAreaCode())) {
//            nodeApply.setNodeIdcode(nodeIdcode + nodeApply.getAreaCode());
//        }else if(StringUtils.isNotBlank(nodeApply.getCityCode())) {
//            nodeApply.setNodeIdcode(nodeIdcode + nodeApply.getCityCode());
//        }else{
//            nodeApply.setNodeIdcode(nodeIdcode + nodeApply.getProvinceCode());
//        }
        return nodeMapper.updateNodeApply(nodeApply);
    }

    public List<GeNodeApply> findNodeApplyByNodeName(String nodeName) {
        return nodeMapper.findNodeApplyByNodeName(nodeName);
    }

    public List<GeNode> findNodeByNodeName(String nodeName) {
        return nodeMapper.findNodeByNodeName(nodeName);
    }

    public List<NodeVo> selectUnitNodeList(Integer unitId, Integer nodeType, Integer state, String keywords, Integer page, Integer limit) {
        PageHelper.startPage(page, limit);
        return nodeMapper.selectUnitNodeList(unitId, nodeType, state, keywords);
    }

    public List<GeNodeApply> findNodeApplyByAddressCode(String provinceCode, String cityCode, String areaCode) {
        return nodeMapper.findNodeApplyByAddressCode(provinceCode, cityCode, areaCode);
    }

    @Transactional
    public void addAssess(GeAuth geAuth) {
        geAuth.setAuthExamineState(EnumFile.ExamineState.Wait);
        authMapper.insertSelective(geAuth);
    }

    public List<NodeApplyVo> selectEscalationDataList(Integer isEscalation, String keywords, String startTime, String endTime, Integer page, Integer limit) {
        PageHelper.startPage(page, limit);
        return nodeMapper.selectEscalationDataList(isEscalation, keywords, startTime, endTime);
    }

}
